package test.demos.ireport.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

public class CommonDataSource implements JRDataSource {

	protected List<Object> dataList;

	protected int index = -1;

	private static final Logger log = LoggerFactory.getLogger(CommonDataSource.class);

	public CommonDataSource(List<Object> dataList) {
		super();
		this.dataList = dataList;
	}

	@Override
	public boolean next() throws JRException {
		index++;
		return (index < dataList.size());
	}

	@Override
	public Object getFieldValue(JRField field) {

		String fieldName = field.getName();
		String firstCharater = fieldName.substring(0, 1);
		String firstCharaterToUpper = firstCharater.toUpperCase();
		fieldName = fieldName.replaceFirst(firstCharater, firstCharaterToUpper);
		Object object = (Object) dataList.get(index);
		Object addResult = null;
		Class<? extends Object> classType = object.getClass();
		Method getMethod = null;
		StringBuffer methodName = new StringBuffer();

		try {
			getMethod = classType.getMethod(methodName.append("get").append(fieldName).toString());

		} catch (NoSuchMethodException nse) {
			log.error("[getFieldValue] has NoSuchMethodException :" + nse.getMessage());
			log.debug("[getFieldValue] Try to use IS method");
			methodName = new StringBuffer();
			try {
				getMethod = classType.getMethod(methodName.append("is").append(fieldName).toString());

			} catch (NoSuchMethodException e) {
				log.error("[getFieldValue] has SecurityException :" + e.getMessage());
				return null;
			}
		}

		try {
			addResult = getMethod.invoke(object);
			if (addResult != null) {
				if (addResult instanceof Integer) {
					return ((Integer) addResult).toString();
				}
				if (addResult instanceof Long) {
					return ((Long) addResult).toString();
				}
				if (addResult instanceof BigDecimal) {
					return String.valueOf((BigDecimal) addResult);
				}
			}
			return addResult;
		} catch (IllegalAccessException iae) {
			log.error("[getFieldValue] has IllegalAccessException :" + iae.getMessage());
			return null;
		} catch (InvocationTargetException ite) {
			log.error("[getFieldValue] has InvocationTargetException :" + ite.getMessage());
			return null;
		}
	}
}
